/***************************************************************
Title: ONU

Info:
Uart1 - feeder
Uart2 - Optical
SPI2  - DBA Controller communication


****************************************************************/
#include<p24fj128ga006.h>
#include <libpic30.h>
#include "main.h"

#define TX2EN U2STAbits.UTXEN

_CONFIG1(JTAGEN_OFF & GCP_OFF & GWRP_OFF & BKBUG_OFF & COE_OFF & FWDTEN_OFF)
_CONFIG2(FCKSM_CSDCMD & OSCIOFNC_ON & POSCMOD_HS & FNOSC_PRIPLL)


/*************************************************************************************
Initilize function start hire
**************************************************************************************/


void init_timer1(void)
{
   _T1IP = 4; //set timer1 priority (4 = default)
   TMR1 = 0; //clear the timer 
   PR1 = 34; //set the period register 140us
   T1CON = 0x8020; //check T1CON register (1:64)
   _T1IF = 0; //clear interrupt flag
   _T1IE = 1; //enable T1 interrupt source   
}


void init_uart1(void)
{
   //TX
   U1BRG = 35;//init U1BRG reg
   U1MODE = 0x8008;//set the number 8,n,1
   U1STA = 0x0400;//disable uart module

   //RX
   IEC0bits.U1RXIE = 1;//Set enable rx interrupt
   _U1RXIP = 0x07;//interrupt prirority IPC2
   //urxsel<1:0> uxsta<7:6> U1STA 00, interrupt each char in
  
}
void init_uart2(void)
{
   //TX
   U2BRG = 35;//init U1BRG reg 115.2kbps
   U2MODE = 0x8008;//set the number 8,n,1
   U2STA = 0x0000;//enable uart module

   //RX
   IEC1bits.U2RXIE = 1;//Set enable rx interrupt
   _U2RXIP = 0x07;//interrupt prirority IPC2
   //urxsel<1:0> uxsta<7:6> U2STA 00, interrupt each char in
  
}

void wdt_(void)
{
    if(wdt_ctr>10000)
    {
        wdt_led = wdt_led ^ 0x01;
        wdt_ctr = 0x00;
        //U1TXREG = in_ctr;//.....
    }
}

void buffer_clr(void)
{
   if(in_ctr1 > 100)
   {
     in_ctr1 = 0x00;
   }
}


void SChar(unsigned char in)
{
    __delay32(5000);
   U2TXREG = in;   
    __delay32(20000);
   TX2EN = 0x00;
}

/**************************************************************************
ONU Network management segmnent
***************************************************************************/

void REPORT_Normal(void)
{
    int i;//,j,pointer;
    //unsigned char dat_test;
     
    //Preamble
    EthernetMPCP[0] = SPD;
    EthernetMPCP[1] = Reserved;
    EthernetMPCP[2] = Reserved;
    EthernetMPCP[3] = SLD;
    EthernetMPCP[4] = Reserved;
    EthernetMPCP[5] = Reserved;
    for(i=0;i<2;i++)
    {
       EthernetMPCP[i+6] = LLID_addr[i];  
    }
    EthernetMPCP[8] = 0x00;//CRC8
    //MPCP 
    for(i=0;i<6;i++)//DA
    {           
      EthernetMPCP[9+i] =  OLT_MACAddr[i];//DA
    }  
    for(i=0;i<6;i++)//SA
    {           
      EthernetMPCP[15+i] =  ONU_MACAddr[i];//SA
    }   
    EthernetMPCP[21] = 0x88;//type_length
    EthernetMPCP[22] = 0x08;//type_length
    EthernetMPCP[23] = 0x00;//opcode
    EthernetMPCP[24] = 0x03;//opcode
    EthernetMPCP[25] = (timer_counter32 & 0x000000FF);//timestamp
    EthernetMPCP[26] = (timer_counter32 & 0x0000FF00)>>8;//timestamp
    EthernetMPCP[27] = (timer_counter32 & 0x00FF0000)>>16;//timestamp
    EthernetMPCP[28] = (timer_counter32 & 0xFF000000)>>24;//timestamp
    //EthernetMPCP[29] = 0x77;//number of q set - from dba agent
    
    for(i=0;i<25;i++)//copy data q(no of q set,report bitmap,qreport
    {
      //EthernetMPCP[30+i] = 0x00;//data[i]; 
      EthernetMPCP[29+i] = queue_list[i+1];//data[i];
    }
    EthernetMPCP[70] = 'A';//number of grand/flag
    EthernetMPCP[71] = 0x0D;//number of grand/flag
    EthernetMPCP[72] = 0x0A;//number of grand/flag    
    
   
    TX2EN = 0x01;
    __delay32(5000);
    for(i=0;i<sizeof(EthernetMPCP);i++)//send to optical
    {
       U2TXREG = EthernetMPCP[i];
       //__delay32(30000);//delay for cater the reflection     
       __delay32(20000);
    }
    U2STAbits.UTXEN = 0x00;
    //TX2EN = 0x00;
}


void eter_data(unsigned int type_length)
{
    int i;//,j,pointer;
    //unsigned char dat_test;
     
    //Preamble
    EthernetMPCP[0] = SPD;
    EthernetMPCP[1] = Reserved;
    EthernetMPCP[2] = Reserved;
    EthernetMPCP[3] = SLD;
    EthernetMPCP[4] = Reserved;
    EthernetMPCP[5] = Reserved;
    for(i=0;i<2;i++)
    {
       EthernetMPCP[i+6] = LLID_addr[i];  
    }
    EthernetMPCP[8] = 0x00;//CRC8
    //MPCP 
    for(i=0;i<6;i++)//DA
    {           
      EthernetMPCP[9+i] =  OLT_MACAddr[i];//DA
    }  
    for(i=0;i<6;i++)//SA
    {           
      EthernetMPCP[15+i] =  ONU_MACAddr[i];//SA
    }   
    EthernetMPCP[21] = type_length & 0x00FF;//type_length
    EthernetMPCP[22] = (type_length & 0xFF00)>>8;//type_length
    EthernetMPCP[23] = 0x00;//opcode
    EthernetMPCP[24] = 0x03;//opcode
    EthernetMPCP[25] = (timer_counter32 & 0x000000FF);//timestamp
    EthernetMPCP[26] = (timer_counter32 & 0x0000FF00)>>8;//timestamp
    EthernetMPCP[27] = (timer_counter32 & 0x00FF0000)>>16;//timestamp
    EthernetMPCP[28] = (timer_counter32 & 0xFF000000)>>24;//timestamp
    //EthernetMPCP[29] = 0x77;//number of q set - from dba agent
    
    for(i=0;i<25;i++)//copy data q(no of q set,report bitmap,qreport
    {
      //EthernetMPCP[30+i] = 0x00;//data[i]; 
      EthernetMPCP[29+i] = 0x00;
    }
    EthernetMPCP[70] = 'A';//number of grand/flag
    EthernetMPCP[71] = 0x0D;//number of grand/flag
    EthernetMPCP[72] = 0x0A;//number of grand/flag    
    
   
    TX2EN = 0x01;
    __delay32(5000);
    for(i=0;i<sizeof(EthernetMPCP);i++)//send to optical
    {
       U2TXREG = EthernetMPCP[i];
       //__delay32(30000);//delay for cater the reflection     
       __delay32(20000);
    }
    U2STAbits.UTXEN = 0x00;
    //TX2EN = 0x00;
}


int main(void)
{
    int z;

    init_timer1();
    init_uart1();
    init_uart2();
/*
    U1TXREG = 'A';      
    TX2EN = 0x01;
    __delay32(5000);
    for(z=0;z<10;z++)//send to optical
    {
       U2TXREG = 0xAA;
       //__delay32(30000);//delay for cater the reflection     
       __delay32(20000);
    }
    TX2EN = 0x00;
*/
    while(1)
    {
       process_URX1();
       process_URX2();
       buffer_clr();
       chk_report_buffer();
       wdt_();
       chk_report_buffer(); 
       /*****add user define function below this line******/
       send_1st_report();//dba send report
 
 
    }

}


/*********************************************************
     iNTERRUPT 
*********************************************************/
//Actual TQ def = 16ns or time require to tx 2 byte of data at 1Gbps line rate
//Current 140us or time require to tx 2 byte of data it 115.2kbps line rate
void __attribute__((interrupt, no_auto_psv)) _T1Interrupt()
{
   timer_counter32++; // system time counter 32bit increament every 4ns 
   if(timer_counter32 == 0xFFFF){
     timer_counter32 = 0x00; 
     //scan_ctr = 0x00;
   }
   wdt_ctr++;  
   _T1IF = 0;
}

//void _ISR _U1RXInterrupt(void)
void __attribute__((interrupt, no_auto_psv)) _U1RXInterrupt()
{
   unsigned char datax;

   datax = U1RXREG;
   if((datax == 0x02)&&(in_ctr1 == 0x00))  //SOF detect
   {
           in1_buffer[in_ctr1++] = datax;
           //U1TXREG = 0x01;
   }
   else if(in_ctr1 != 0x00)//normal data
   {
            in1_buffer[in_ctr1++] = datax;
   }

   if((in_ctr1 != 0x00)&&(in1_buffer[in1_buffer[4]+5] == 0x03))//EOF detech
   {
            //U1TXREG = 0x01;
            in1_buffer[in1_buffer[4]+5] = 0x00;
            URX1_Ready = 0x01;
            in_ctr1 = 0x00;
   }
  
   
   IFS0bits.U1RXIF = 0; 
}

//void _ISR _U2RXInterrupt(void)
void __attribute__((interrupt, no_auto_psv)) _U2RXInterrupt()
{
   unsigned char data;
   

   data = U2RXREG; 

   if((data == 0x02)&&(in_ctr2 == 0x00))
   {
      in2_buffer[in_ctr2++]=data;    
      // = 0x01;   
   }
   else if((data == 0x55)&&(in_ctr2 == 0x01))
   {
      in2_buffer[in_ctr2++]=data;           
   }
   else if((data == 0x55)&&(in_ctr2 == 0x02))
   {
      in2_buffer[in_ctr2++]=data;      
   }
   else if((data == 0xD5)&&(in_ctr2 == 0x03))
   {
      in2_buffer[in_ctr2++]=data;      
   }
   else if((data == 0x55)&&(in_ctr2 == 0x04))
   {
      in2_buffer[in_ctr2++]=data;     
   }
   else if((data == 0x55)&&(in_ctr2 == 0x05))
   {
      in2_buffer[in_ctr2++]=data;      
   }
   else if(in_ctr2>5)
   {
     in2_buffer[in_ctr2++]=data;
     if(in_ctr2 == 23)
     {
         length_type = (((in2_buffer[21] | length_type)<< 8)| in2_buffer[22]);
     }
     else if(in_ctr2 > 70)
     {
         if(length_type <= 0x05DE)//data
         {
              if(in_ctr2 == length_type)
              {
                 URX2_Ready = 0x02;
                 in_ctr2 = 0x00; 
              } 
         }
         else//ether type
         {
              if(in_ctr2 == 73)//MPCP
              {
                 URX2_Ready = 0x01;
                 in_ctr2 = 0x00; 
                 //TX2EN = 0x00;

              } 
         }
     } 
   } 
   IFS1bits.U2RXIF = 0;  

}

